#ifndef __GE_TEXTUREOBJ_H__
#define __GE_TEXTUREOBJ_H__

/*
	DDS Loading code based on SOIL library's implementation.
*/

#include "GE_Base.h"

namespace Syp
{
	/*	The dwFlags member of the original DDSURFACEDESC2 structure
	can be set to one or more of the following values.	*/
#define DDSD_CAPS	0x00000001
#define DDSD_HEIGHT	0x00000002
#define DDSD_WIDTH	0x00000004
#define DDSD_PITCH	0x00000008
#define DDSD_PIXELFORMAT	0x00001000
#define DDSD_MIPMAPCOUNT	0x00020000
#define DDSD_LINEARSIZE	0x00080000
#define DDSD_DEPTH	0x00800000

	/*	DirectDraw Pixel Format	*/
#define DDPF_ALPHAPIXELS	0x00000001
#define DDPF_FOURCC	0x00000004
#define DDPF_RGB	0x00000040

	/*	The dwCaps1 member of the DDSCAPS2 structure can be
	set to one or more of the following values.	*/
#define DDSCAPS_COMPLEX	0x00000008
#define DDSCAPS_TEXTURE	0x00001000
#define DDSCAPS_MIPMAP	0x00400000

	/*	The dwCaps2 member of the DDSCAPS2 structure can be
	set to one or more of the following values.		*/
#define DDSCAPS2_CUBEMAP	0x00000200
#define DDSCAPS2_CUBEMAP_POSITIVEX	0x00000400
#define DDSCAPS2_CUBEMAP_NEGATIVEX	0x00000800
#define DDSCAPS2_CUBEMAP_POSITIVEY	0x00001000
#define DDSCAPS2_CUBEMAP_NEGATIVEY	0x00002000
#define DDSCAPS2_CUBEMAP_POSITIVEZ	0x00004000
#define DDSCAPS2_CUBEMAP_NEGATIVEZ	0x00008000
#define DDSCAPS2_VOLUME	0x00200000



	struct TexOptions
	{
		TextureObj* tex;
		bool buildMipMaps;//should we build mipmaps
		bool compressTextures;//should textures be compressed on upload		
		String filename;

	};

	/**	A bunch of DirectDraw Surface structures and flags **/
	struct DDS_header
	{
		unsigned int    dwMagic;
		unsigned int    dwSize;
		unsigned int    dwFlags;
		unsigned int    dwHeight;
		unsigned int    dwWidth;
		unsigned int    dwPitchOrLinearSize;
		unsigned int    dwDepth;
		unsigned int    dwMipMapCount;
		unsigned int    dwReserved1[ 11 ];

		/*  DDPIXELFORMAT	*/
		struct
		{
			unsigned int    dwSize;
			unsigned int    dwFlags;
			unsigned int    dwFourCC;
			unsigned int    dwRGBBitCount;
			unsigned int    dwRBitMask;
			unsigned int    dwGBitMask;
			unsigned int    dwBBitMask;
			unsigned int    dwAlphaBitMask;
		}
		sPixelFormat;

		/*  DDCAPS2	*/
		struct
		{
			unsigned int    dwCaps1;
			unsigned int    dwCaps2;
			unsigned int    dwDDSX;
			unsigned int    dwReserved;
		}
		sCaps;
		unsigned int    dwReserved2;
	};

	///TextureObj stores information of a texture. The file it is loaded from, number of MeshInstances using it, it's id.
	class SYPAPI TextureObj : public Resource
	{	
		friend class Renderer;
	public:
		TextureObj(const String& filename);	
		///Loads a texture and returns a pointer to a TextureObj.
		static TextureObj* loadTexture(const String& filename,bool buildMipMaps = true,bool compressTextures = true, bool async = true); ///	duh
		///Loads a texture from memory,
		///name specifies desired name for the object
		///TexOptions is a pointer to a TexOptions structure defining properties of the texture
		///width and height define the width and height of the texture
		///data contains the bitmap information
		///format contains the format of the image data
		///now indicates if the texture should be loaded immediately instead of being qued
		static TextureObj* loadFromMemory(TexOptions* to, PInt width, PInt height, unsigned char* data, Syp::TextureFormat format, Syp::TextureFormat internalFormat, bool now = false);
		///Pass a tex if you want it load the texture into tex
		///data is a pointer to a pointer which will contain the image data
		static TextureObj* loadDDSFromMemory(const unsigned char *const buffer,
			PInt buffer_length,		
			int loading_as_cubemap,
			unsigned char** data,
			TextureObj* tex=0
			);
		virtual void dumpResourceInfo();
		PInt getWidth();
		PInt getHeight();
	private:	
		//Multi-threaded function which loads actual file in another thread.
		static void doLoad(void* arg);
		//static void _stdcall doLoad(void* arg);
		///ID used by OpenGL to recognise the texture
		PInt id;	
		friend struct SubMaterial;
		/*friend void SubMaterial::useTexture(TextureObj* txtID);
		friend void SubMaterial::clearTexture();*/
		PInt width;
		PInt height;
		PInt dataSize;//used for determining compressedTexture's size
		TextureFormat format;
		TextureFormat internalFormat;
		bool hasMipMaps;
		~TextureObj();

	};
}

#endif //__GE_TEXTUREOBJ_H__

